home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000
/
Ham Radio 2000.iso
/
ham2000
/
satellit
/
vstsrc
/
rotator.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-25
|
15KB
|
433 lines
/*
* %W% %E% %U% [EXTREL_1.2]
*
* VersaTrack orbit calculations are based on those that appear in Dr. Manfred
* Bester's sattrack program (the Unix(tm) versions 1 and 2).
*
* The data from which the maps where generated come from "xsat", an
* X-Windows program by David A. Curry (N9MSW).
*
* Site coordinates come from various sources, including a couple of
* World Almanacs, and also from both of the programs mentioned above.
*
* The following are authors' applicable copyright notices:
*
*
* Copyright (c) 1992, 1993, 1994 Manfred Bester. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for educational, research and non-profit purposes, without
* fee, and without a written agreement is hereby granted, provided that the
* above copyright notice and the following three paragraphs appear in all
* copies.
*
* Permission to incorporate this software into commercial products may be
* obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way,
* Berkeley, CA 94709, USA.
*
* IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF
* THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"
* BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
* UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*
* Copyright 1992 by David A. Curry
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation. The
* author makes no representations about the suitability of this software for
* any purpose. It is provided "as is" without express or implied warranty.
*
* David A. Curry, N9MSW
* Purdue University
* Engineering Computer Network
* 1285 Electrical Engineering Building
* West Lafayette, IN 47907
* davy@ecn.purdue.edu
*
* VersaTrack Copyright (c) 1993, 1994 Siamack Navabpour. All Rights Reserved.
*
* Permission is hereby granted to copy, modify and distribute VersaTrack
* in whole, or in part, for educational, non-profit and non-commercial use
* only, free of charge or obligation, and without agreement, provided that
* all copyrights and restrictions noted herein are observed and followed, and
* additionally, that this and all other copyright notices listed herein
* appear unaltered in all copies and in all derived work.
*
* This notice shall not in any way void or supersede any of the other authors
* rights or privileges.
*
* VersaTrack IS PRESENTED FREE AND "AS IS", WITHOUT ANY WARRANTY OR SUPPORT.
* YOU USE IT AT YOUR OWN RISK. The author(s) shall not be liable for any
* direct, indirect, incidental, or consequential damage, loss of profits or
* other tangible or intangible losses or benefits, arising out of or related
* to its use. VersaTrack carries no warranty, explicit or implied, including
* but not limited to those of merchantablity and fitness for a particular
* purpose.
*
* Siamack Navabpour, 12342 Hunter's Chase Dr. Apt. 2114, Austin, TX 78729.
* sia@bga.com or sia@realtime.com.
*/
#include <windows.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "vstdefs.h"
#include "vsttype.h"
#include "vstextrn.h"
exserver_t serverInfo[2] = {
{ "RadioControl",
"\\\\.\\PIPE\\_VRADIO_",
ST_SRV_NONE, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL, { 0 }, { 0 },
FmtProc
},
{ "RotatorControl",
"\\\\.\\PIPE\\_VROTAT_",
ST_SRV_NONE, 0, 0,
NULL, NULL, NULL, NULL, NULL, NULL, { 0 }, { 0 },
FmtProc
},
};
static HANDLE hth;
BOOL
ServerCreate(exserver_t *exp, void *vp)
{
DWORD dummy;
extern int ServerStart();
extern char *ErrorString(int);
if (vp == NULL)
return FALSE;
exp->srv_vp = vp;
if (currentSel)
exp->srv_sp = currentSel;
else if (selInfo)
exp->srv_sp = selInfo;
else
exp->srv_sp = NULL;
if (exp->srv_flags & 0x2) /* XXX read lock needed */
return FALSE;
exp->srv_flags |= 2; /* XXX write lock needed */
hth = CreateThread(NULL, 0, (PTHREAD_START_ROUTINE) ServerStart,
(LPVOID) exp, (DWORD) 0, (DWORD *)&dummy);
if ((hth == NULL) || (hth == INVALID_HANDLE_VALUE)) {
exp->srv_flags &= ~0x2;
sprintf(tmpbuf,"Cannot start service: %s", ErrorString(GetLastError()));
usermsg(tmpbuf);
return FALSE;
}
return TRUE;
}
static BOOL
/* needed to protect aginst missing reload (optimizer bug?) */
ServerTerminate(exserver_t *exp)
{
return (exp->srv_flags & 0x1) ? TRUE : FALSE;
}
static BOOL
ServerSend(exserver_t *exp, char *buf)
{
BOOL status;
int written, result, error;
status = WriteFile (exp->srv_hpipe, buf, 100,
&written, &exp->srv_WrOverlap);
error = GetLastError();
if (!status && error == ERROR_IO_PENDING) {
result = WaitForSingleObject (exp->srv_WrEvent, (DWORD)-1);
if (result != WAIT_OBJECT_0)
status = FALSE;
else
status = GetOverlappedResult(exp->srv_hpipe,
&exp->srv_WrOverlap, &written, FALSE);
}
#ifdef _DEBUG_
diag("ServerSend: returning %d\n", status);
#endif
return status;
}
static int
ServerStart(exp)
exserver_t *exp;
{
int e, i, n;
extern void ServerProc(void *);
select_t *sp;
BOOL error, flag, (*libfunc)(int, HWND, select_t *, void *);
extern BOOL ServerInit(exserver_t *);
extern void *LibFunc(const char *), LibClose(void);
extern char *ErrorString(int);
ASSERT(exp);
if (!(sp = exp->srv_sp)) {
exp->srv_flags &= ~0x2; /* write lock needed */
return 0;
}
if (exp->srv_hpipe || (exp->srv_state != ST_SRV_NONE)) {
SetWindowText(Gwnd,VersionStr);
usermsg("Server already running or busy");
exp->srv_flags &= ~0x2;
return 0;
}
error = FALSE;
flag = FALSE;
SetWindowText(Gwnd, "Trying to connect to server. Please Wait...");
for (n = 0; n < 3; n++) {
for (i = 0; i< 20; i++) {
exp->srv_hpipe = CreateFile (exp->srv_pipename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE , NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (exp->srv_hpipe != INVALID_HANDLE_VALUE) {
exp->srv_thread_handle = CreateThread(NULL, 0,
(PTHREAD_START_ROUTINE) ServerProc,
(LPVOID) exp, (DWORD) 0, (DWORD *)&e);
if ((exp->srv_thread_handle == INVALID_HANDLE_VALUE) ||
(exp->srv_thread_handle == NULL) ) {
sprintf(tmpbuf,"Cannot create service thread: %s",
ErrorString(GetLastError()));
usermsg(tmpbuf);
exp->srv_thread_handle = NULL;
error = TRUE;
break;
}
exp->srv_state = ST_SRV_RUNNING;
SetWindowText(Gwnd, VersionStr);
exp->srv_flags &= ~0x2;
return 0;
}
else {
exp->srv_hpipe = NULL;
e = GetLastError();
if ((e == ERROR_SEEK_ON_DEVICE) || (e == ERROR_FILE_NOT_FOUND))
Sleep(500);
else {
sprintf(tmpbuf, "can't open channel to control server - error code %d", error);
usermsg(tmpbuf);
error = TRUE;
break;
}
}
}
if (flag)
break;
if (error) {
usermsg("Unable to start or connect to server");
break;
}
if (!(libfunc = (void (*)) LibFunc(exp->srv_libfun))) {
LibClose();
usermsg(dllinvalidmsg);
break;
}
flag = TRUE;
error = ! (*libfunc)(VSTVERSION, Gwnd, exp->srv_sp, exp->srv_vp);
LibClose();
if (error)
break;
}
SetWindowText(Gwnd, VersionStr);
exp->srv_flags &= ~0x2;
return 0;
}
void
ServerProc(exserver_t *exp)
{
select_t *sp;
BOOL done, first;
int nslp, when;
HANDLE intr;
char buf[256];
#ifdef _DEBUG_
diag("PIPE ServerProc started.\n");
#endif
ASSERT(exp);
if (!(sp = exp->srv_sp))
goto finish;
intr = sp->rtd_thread_handle;
exp->srv_WrEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
exp->srv_WrOverlap.hEvent = exp->srv_WrEvent;
exp->srv_RdEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
exp->srv_RdOverlap.hEvent = exp->srv_RdEvent;
when = 0;
done = FALSE;
first = TRUE;
#ifdef _DEBUG_
diag("Server thread started. exp %x sp %x\n", exp, sp);
#endif /* _DEBUG_ */
sprintf(buf,"> HELLO %02d 1 WH %08x SEQ %d", VSTVERSION, Gwnd,
exp->srv_seq = (time(0) & 63));
exp->srv_seq++;
if (ServerSend(exp, buf)) do {
if (sp->rtd_thread_handle) {
if (currentSel && sp != currentSel) {
sprintf(buf,"! %03d 'SAT CHANGED'", exp->srv_seq);
first = TRUE;
exp->srv_sp = sp = currentSel;
intr = sp->rtd_thread_handle;
}
else {
if (first) {
first = FALSE;
(*(exp->srv_fmtproc))(FMT_INIT, exp->srv_seq, exp, sp, buf);
}
else
(*(exp->srv_fmtproc))(FMT_FMT, exp->srv_seq, exp, sp, buf);
}
}
else {
first = TRUE;
sprintf(buf,"! %03d 'STOPPED'", exp->srv_seq);
if (currentSel)
exp->srv_sp = sp = currentSel;
}
exp->srv_seq++;
done = !ServerSend(exp, buf);
if (!done) {
nslp = sp->rtd_thread_handle ? (sp->updatetime << 1) : 20;
while (intr == sp->rtd_thread_handle && when++ < nslp)
Sleep((DWORD) 500);
when = 0;
intr = sp->rtd_thread_handle;
}
done = done || ServerTerminate(exp);
} while (!done);
usermsg("External server disconnected or gone. Terminating connection.");
CloseHandle(exp->srv_WrEvent);
DeleteObject(exp->srv_WrEvent);
CloseHandle(exp->srv_RdEvent);
DeleteObject(exp->srv_RdEvent);
exp->srv_WrEvent = NULL;
finish:
if (exp->srv_hpipe) {
CloseHandle(exp->srv_hpipe);
exp->srv_hpipe = NULL;
}
PostMessage(Gwnd, EXTM_THEXIT, (WPARAM) 0, (LPARAM) exp->srv_thread_handle);
Sleep(0);
PostMessage(Gwnd, EXTM_THEXIT, (WPARAM) 0, (LPARAM) hth);
Sleep(0);
hth = exp->srv_thread_handle = NULL;
exp->srv_state = ST_SRV_NONE;
exp->srv_flags = 0;
ExitThread(0);
}
void
FmtProc(int op, int seqq, exserver_t *exp, select_t *sp, char *buf)
{
track_t *tp;
result_t *rp;
satellite_t *satp;
site_t *sitep;
buf[0] = 0;
if (!sp)
return;
tp = sp->sl_tp;
rp = sp->sl_rp;
satp = tp->satp;
sitep = tp->sitep;
switch (op) {
case FMT_INIT:
sprintf(buf,"* %03d INIT UPD %04d MIE %3.1lf MD '%3.3s' SITE '%s' SAT '%s'",
seqq, sp->updatetime, tp->minelevation, rp->r_modestr,
sitep->c_name, satp->s_name);
break;
case FMT_FMT:
if (sp->rtd_thread_handle)
rtd_lock(sp);
sprintf(buf,"+ %03d AZ %+03.1lf EL %+03.1lf RNG %+07.0lf.0 DV %+04.7lf PL %4.1lf %s",
seqq, rp->r_azimuth, rp->r_elevation, rp->r_range, rp->r_rangerate,
rp->r_pathloss, satp->s_name);
if (sp->rtd_thread_handle)
rtd_unlock(sp);
break;
default:
buf[0] = 0;
break;
}
}
void
ServerDestroy()
{
exserver_t *exp;
int i;
for (i=0,exp = &serverInfo[0]; i<2; i++) {
if (exp->srv_state != ST_SRV_NONE) {
if (exp->srv_thread_handle) {
exp->srv_flags |= 1; /* HACK */
WaitForSingleObject(exp->srv_thread_handle, (DWORD)25000);
}
}
}
}